package org.balthie.demo.jdk.util.concurrent.future.forkjoin;

import java.text.MessageFormat;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;

public class LineSearchTask extends RecursiveTask<Integer>
{
    private static final long serialVersionUID = 1L;
    
    private String[] line;
    
    private int start, end;
    
    private String word;
    
    public LineSearchTask(String[] line, int start, int end, String word)
    {
        super();
        this.line = line;
        this.start = start;
        this.end = end;
        this.word = word;
    }
    
    @Override
    protected Integer compute()
    {
        int result = 0;
        if(end - start < 100)
        {
            result = count(line, start, end, word);
            System.out.println(MessageFormat.format("【{0}】countword【{1}】Lines【{2}】 appears 【{3}】times at【{4, time, HH:mm:ss:ms}】",
                    Thread.currentThread().getName(), end - start, word, result, new Date()));
        }
        else
        {
            int mid = (start + end) / 2;
            LineSearchTask task1 = new LineSearchTask(line, start, mid, word);
            LineSearchTask task2 = new LineSearchTask(line, mid, end, word);
            invokeAll(task1, task2);
            try
            {
                result = groupResults(task1.get(), task2.get());
            }
            catch (InterruptedException | ExecutionException e)
            {
                e.printStackTrace();
            }
        }
        
        return result;
    }
    
    private int groupResults(Integer integer1, Integer integer2)
    {
        return integer1 + integer2;
    }
    
    private int count(String[] line, int start, int end, String word)
    {
        int counter = 0;
        
        for(String w : line)
        {
            System.out.println(String.format("【%s】 [%s] equals [%s] is  [%s]", Thread.currentThread().getName(), word, w, word.equals(w)));
            if(word.equals(w))
            {
                counter++;
            }
        }
        
        try
        {
            TimeUnit.MILLISECONDS.sleep(10);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        
        return counter;
    }
    
}
